package com.wetool.exception;

import com.wetool.exception.invoicing.AddPlacingException;
import com.wetool.exception.invoicing.AddStorageException;
import com.wetool.exception.invoicing.AddSupplierException;
import com.wetool.exception.invoicing.BillException;
import com.wetool.exception.invoicing.DeleteFailedException;
import com.wetool.exception.invoicing.DocumentsNotFindException;
import com.wetool.exception.invoicing.InsufficientStockException;
import com.wetool.exception.invoicing.InventorySurplusException;
import com.wetool.exception.invoicing.ParamCheckException;
import com.wetool.exception.invoicing.PlacingNotFindException;
import com.wetool.exception.invoicing.ShopNotLoginException;
import com.wetool.exception.invoicing.SplitCommodityException;
import com.wetool.exception.invoicing.SpplitNotFindException;
import com.wetool.exception.invoicing.StorageNotFindException;
import com.wetool.exception.invoicing.UpdatePlacingException;
import com.wetool.exception.invoicing.UpdateStorageException;
import com.wetool.model.Message;
import com.wetool.model.Message.Result;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.text.ParseException;
import java.util.List;

/**
 * 描述：自定义异常处理
 * 
 * @author lixin
 * @since 1.0
 */
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
	private static final Logger logger = LogManager.getLogger(CustomExceptionHandler.class);
	
	/** 通用异常 */
	@ExceptionHandler(Exception.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> error(Exception e) {
		logger.error(Result.ERROR, e);
		return new ResponseEntity<>(new Message<>(Result.ERROR), HttpStatus.OK);
	}

	/**描述：数据关联异常*/
	@ExceptionHandler(DataRelationException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> hasChildrenData(DataRelationException e) {
		logger.error(Result.ERR_DATA_RELATION, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_DATA_RELATION), HttpStatus.OK);
	}

	/**描述： 目录节点关联异常*/
	@ExceptionHandler(CategoryNotFindException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> categoryNotFind(CategoryNotFindException e) {
		logger.error(Result.ERR_CATEGORY_NOTFIND, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_CATEGORY_NOTFIND), HttpStatus.OK);
	}
	
	/**描述： 目录节点关联异常*/
	@ExceptionHandler(NodeRelationException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> hasChildrenNode(NodeRelationException e) {
		logger.error(Result.ERR_NODE_RELATION, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_NODE_RELATION), HttpStatus.OK);
	}

	/**描述： 改变节点类型异常*/
	@ExceptionHandler(ChangeIsLeafException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> noChangeIsLeaf() {
		return new ResponseEntity<>(new Message<>(Result.ERR_CHANGE_ISLEAF), HttpStatus.OK);
	}

	/**描述：查询商品找不到异常*/
	@ExceptionHandler(CommodityNotFindException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> commodityNotFind() {
		return new ResponseEntity<>(new Message<>(Result.ERR_NOTFIND_COMMODITY), HttpStatus.OK);
	}

	/**描述： 参数校验异常*/
	@ExceptionHandler(ParamCheckException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> paramCheck(ParamCheckException ex) {
		String message = getErrMessage(ex.getAllErrors());
		logger.error(Result.ERR_PARAMCHECK, ex);
		return new ResponseEntity<>(new Message<>(Result.ERR_PARAMCHECK, message), HttpStatus.OK);
	}
	
	/**描述：商品信息修改失败*/
	@ExceptionHandler(CommodityUpdateException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> commodityUpdate(CommodityUpdateException e) {
		logger.error(Result.ERR_COMMODITY_UPDATE, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_COMMODITY_UPDATE), HttpStatus.OK);
	}

	@ExceptionHandler(ClassNotFoundException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> classNotFound(ClassNotFoundException e) {
		logger.error(Result.ERR_CLASS_NOTFIND, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_CLASS_NOTFIND), HttpStatus.OK);
	}

	@ExceptionHandler(IllegalArgumentException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> illegalArgument(IllegalArgumentException e) {
		logger.error(Result.ERR_ILLEGAL_ARGUMENT, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_ILLEGAL_ARGUMENT), HttpStatus.OK);
	}

	@ExceptionHandler(IllegalAccessException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> illegalAccess(IllegalAccessException e) {
		logger.error(Result.ERR_ILLEGAL_ACCESS, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_ILLEGAL_ACCESS), HttpStatus.OK);
	}

	/**格式异常*/
	@ExceptionHandler(FormatException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> format(FormatException e) {
		logger.error(Result.ERR_FORMAT, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_FORMAT), HttpStatus.OK);
	}

	/**分类为目录不能添加商品*/
	@ExceptionHandler(CategoryIsLeafException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> categoryIsLeaf(CategoryIsLeafException e) {
		logger.error(Result.CATEGORY_IS_LEAF, e);
		return new ResponseEntity<>(new Message<>(Result.CATEGORY_IS_LEAF), HttpStatus.OK);
	}
	
	/**商家未登录异常*/
	@ExceptionHandler(MerchantNotLoginException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> merchantNotLogin(MerchantNotLoginException e) {
		logger.error(Result.ERR_MERCHANT_NOT_LOGIN, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_MERCHANT_NOT_LOGIN), HttpStatus.OK);
	}
	
	/**时间格式异常*/
	@ExceptionHandler(ParseException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> parse(ParseException e) {
		logger.error(Result.ERR_PARSE, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_PARSE), HttpStatus.OK);
	}
	
	/**删除商品仍有库存*/
	@ExceptionHandler(InventorySurplusException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> inventorySurplus(InventorySurplusException e) {
		logger.error(Result.ERR_INVENTORY_SURPLUS, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_INVENTORY_SURPLUS), HttpStatus.OK);
	}
	
	/**商品添加失败！*/
	@ExceptionHandler(CommodityAddException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> commodityAdd(CommodityAddException e) {
		logger.error(Result.ERR_ADD_COMMODITY, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_ADD_COMMODITY), HttpStatus.OK);
	}
	
	/**商品存在拆分规则*/
	@ExceptionHandler(SplitRuleExistedException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> splitRuleExisted(SplitRuleExistedException e) {
		logger.error(Result.ERR_SPLITRULE_EXISTED, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_SPLITRULE_EXISTED), HttpStatus.OK);
	}
	
	/**称重商品条形码长度大于４位！*/
	@ExceptionHandler(BarcodeIndexOfException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> barcodeIndexOf(BarcodeIndexOfException e) {
		logger.error(Result.ERR_BARCODE_INDEX_OF, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_BARCODE_INDEX_OF), HttpStatus.OK);
	}
	
	/**商品条形码重复！*/
	@ExceptionHandler(BarcodeRepeatException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> barcodeRepeat(BarcodeRepeatException e) {
		logger.error(Result.ERR_BARCODE_REPEAT, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_BARCODE_REPEAT), HttpStatus.OK);
	}
	
	/**PLU获取失败！*/
	@ExceptionHandler(PLUSaveException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> PLUSaveException(PLUSaveException e) {
		logger.error(Result.ERR_PLU_SAVE, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_PLU_SAVE), HttpStatus.OK);
	}
	
	/**商品分类名称重复！*/
	@ExceptionHandler(CategoryNameRepetitionException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> barcodeRepeat(CategoryNameRepetitionException e) {
		logger.error(Result.ERR_CATEGORY_NAME_REPETITION, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_CATEGORY_NAME_REPETITION), HttpStatus.OK);
	}
	
	/**快录商品信息不存在！*/
	@ExceptionHandler(BePerfectedNotFindException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> bePerfectedNotFind(BePerfectedNotFindException e) {
		logger.error(Result.ERR_BEPERFECTED_NOT_FIND, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_BEPERFECTED_NOT_FIND), HttpStatus.OK);
	}
	
	private String getErrMessage(List<ObjectError> errors) {
		StringBuilder strBuilder = new StringBuilder();
		for (ObjectError error : errors) {
			logger.error(error.getCode() + "---" + error.getDefaultMessage());
			strBuilder.append(error.getDefaultMessage() + "\n");
		}
		return strBuilder.toString();
	}
	
	// 库存不足异常
	@ExceptionHandler(InsufficientStockException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> insufficientStock(InsufficientStockException e) {
		logger.error(Result.ERR_INSUFFICIENT_STOCK, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_INSUFFICIENT_STOCK), HttpStatus.OK);
	}
	
	
	// 商品下有拆分商品（删除商品信息时）
	@ExceptionHandler(SplitCommodityException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> splitCommodity(SplitCommodityException e) {
		logger.error(Result.ER_SPLIT_COMMODITY, e);
		return new ResponseEntity<>(new Message<>(Result.ER_SPLIT_COMMODITY), HttpStatus.OK);
	}


	// 出库信息未找到异常
	@ExceptionHandler(PlacingNotFindException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> placingNotFind(PlacingNotFindException e) {
		logger.error(Result.ERR_NOTFIND_PLACING, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_NOTFIND_PLACING), HttpStatus.OK);
	}

	// 出库信息未找到异常
	@ExceptionHandler(StorageNotFindException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> stroageNotFind(StorageNotFindException e) {
		logger.error(Result.ERR_NOTFIND_STORAGE, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_NOTFIND_STORAGE), HttpStatus.OK);
	}

	// 入库信息添加异常
	@ExceptionHandler(AddPlacingException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> addPlacing(AddPlacingException e) {
		logger.error(Result.ERR_ADD_PLACING, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_ADD_PLACING), HttpStatus.OK);
	}

	// 出库信息添加异常
	@ExceptionHandler(AddStorageException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> addStorage(AddStorageException e) {
		logger.error(Result.ERR_ADD_STORAGE, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_ADD_STORAGE), HttpStatus.OK);
	}

	// 出库信息修改异常
	@ExceptionHandler(UpdatePlacingException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> updatePlacing(UpdatePlacingException e) {
		logger.error(Result.ERR_UPDATE_PLACING, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_UPDATE_PLACING), HttpStatus.OK);
	}
	
	// 供应商添加异常
	@ExceptionHandler(AddSupplierException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> addSupplier(AddSupplierException e) {
		logger.error(Result.ERR_ADD_SUPPLIER, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_ADD_SUPPLIER), HttpStatus.OK);
	}

	// 表单数据已提交异常(不能修改)
	@ExceptionHandler(BillException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> bill(BillException e) {
		logger.error(Result.ERR_BILL, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_BILL), HttpStatus.OK);
	}
	
	// 表单数据修改异常
	@ExceptionHandler(UpdateStorageException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> updateStorage(UpdateStorageException e) {
		logger.error(Result.ERR_UPDATE_STORAGE, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_UPDATE_STORAGE), HttpStatus.OK);
	}
	
	// 店家未登录异常
	@ExceptionHandler(ShopNotLoginException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> shopNotLogin(ShopNotLoginException e) {
		logger.error(Result.ERR_SHOP_NOT_LOGIN, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_SHOP_NOT_LOGIN), HttpStatus.OK);
	}
	
	
	// 店家未登录异常
	@ExceptionHandler(SpplitNotFindException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> spplitNotFind(SpplitNotFindException e) {
		logger.error(Result.ERR_SUPPLIER_NOT_FIND, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_SUPPLIER_NOT_FIND), HttpStatus.OK);
	}
	
	// 无出入库信息异常
	@ExceptionHandler(DocumentsNotFindException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> DocumentsNotFind(DocumentsNotFindException e) {
		logger.error(Result.ERR_DOCUMENTS_NOT_FIND, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_DOCUMENTS_NOT_FIND), HttpStatus.OK);
	}
	
	// 店家未登录异常
	@ExceptionHandler(DeleteFailedException.class)
	@ResponseStatus(HttpStatus.OK)
	public ResponseEntity<?> DocumentsNotFind(DeleteFailedException e) {
		logger.error(Result.ERR_DELETE_FAILED, e);
		return new ResponseEntity<>(new Message<>(Result.ERR_DELETE_FAILED), HttpStatus.OK);
	}
	

}